Processing math: 100%

Prijavi problem


Obeleži sve kategorije koje odgovaraju problemu

Još detalja - opišite nam problem


Uspešno ste prijavili problem!
Status problema i sve dodatne informacije možete pratiti klikom na link.
Nažalost nismo trenutno u mogućnosti da obradimo vaš zahtev.
Molimo vas da pokušate kasnije.

Час 7 - понављање облика коришћењем петљи

Цртање у петљи

Концентрични кругови

Напиши програм који црта концентричне кругове чији је центар у центру екрана, а полупречници су редом 10, 20, …, 100 пиксела. Сваки круг нацртати црвеном линијом дебљином 5 пиксела.

Центар прозора се једноставно израчунава тако да му је координата x на пола ширине, а координата y на пола висине прозора (обрати пажњу на то да се код кругова морају користити цели бројеви, па стога морамо употребити целобројно дељење). Након тога, можемо навести 10 наредби за цртање кругова.

 
1
2
# bojimo pozadinu prozora u belu
3
prozor.fill(pg.Color("white"))
4
# centar kruga je u centru prozora
5
centar = (sirina // 2, visina // 2)
6
pg.draw.circle(prozor, pg.Color("red"), centar, 10, 5)
7
pg.draw.circle(prozor, pg.Color("red"), centar, 20, 5)
8
pg.draw.circle(prozor, pg.Color("red"), centar, 30, 5)
9
pg.draw.circle(prozor, pg.Color("red"), centar, 40, 5)
10
pg.draw.circle(prozor, pg.Color("red"), centar, 50, 5)
11
pg.draw.circle(prozor, pg.Color("red"), centar, 60, 5)
12
pg.draw.circle(prozor, pg.Color("red"), centar, 70, 5)
13
pg.draw.circle(prozor, pg.Color("red"), centar, 80, 5)
14
pg.draw.circle(prozor, pg.Color("red"), centar, 90, 5)
15
pg.draw.circle(prozor, pg.Color("red"), centar, 100, 5)
16
17

(koncentricni_krugovi_peske)

Претходно решење има пуно мана. За почетак, тешко је откуцати оволики број наредби. Даље, ако бисмо се предомислили и променили број кругова или величине полупречника, програм би захтевао доста компликоване измене. Задатак се много боље и једноставније решава када се примети да се полупречници кругова редом мењају од 10 до 100 са кораком 10 (10, 20, 30, …, 90, 100) и када се подсетимо да у Пајтону такво набрајање може остварити петљом:

3
 
1
for i in range(pocetak, kraj, korak):
2
    ...
3

(petlja)

Пошто десни крај није укључен у набрајање (узимају се вредности из полуотвореног интервала [pocetak,kraj)), да би последњи полупречник био 100, за крај је потребно навести вредност 101.

На основу претходне дискусије допуни наредни програм.

20
 
1
import pygame as pg
2
import pygamebg
3
4
(sirina, visina) = (300, 300) # otvaramo prozor
5
prozor = pygamebg.open_window(sirina, visina, "Концентрични кругови")
6
7
# bojimo pozadinu prozora u belo
8
prozor.fill(pg.Color("white"))
9
10
# centar kruga je u centru prozora - obrati pažnju na tip podataka
11
centar = (???, ???)
12
13
# poluprečnik se menja od 10 do 100, sa korakom 10
14
for r in range(10, ???, 10):
15
    # crtamo krug
16
    ???
17
18
# prikazujemo prozor i čekamo da ga korisnik isključi
19
pygamebg.wait_loop()
20

(koncentricni_krugovi)

Мердевине

Измените наредни програм тако да се пречаге мердевина цртају у петљи.

Пажљиво проучи које се вредности мењају кроз позиве функције pg.draw.line, шта је почетна вредност, шта је крајња вредност и који је корак, па на основу тога позови функцију range у оквиру петље for.

23
 
1
import pygame as pg
2
import pygamebg
3
4
(sirina, visina) = (300, 300) # otvaramo prozor
5
prozor = pygamebg.open_window(sirina, visina, "Мердевине")
6
7
prozor.fill(pg.Color("beige")) # bojimo pozadinu ekrana u bež
8
9
# leva strana
10
pg.draw.line(prozor, pg.Color("brown"), (100, 10), (100, visina - 10), 10)
11
# desna strana
12
pg.draw.line(prozor, pg.Color("brown"), (200, 10), (200, visina - 10), 10)
13
14
# ovaj deo prepraviti
15
pg.draw.line(prozor, pg.Color("brown"), (100,  50), (200, 50), 10)  # prečaga
16
pg.draw.line(prozor, pg.Color("brown"), (100, 100), (200, 100), 10) # prečaga
17
pg.draw.line(prozor, pg.Color("brown"), (100, 150), (200, 150), 10) # prečaga
18
pg.draw.line(prozor, pg.Color("brown"), (100, 200), (200, 200), 10) # prečaga
19
pg.draw.line(prozor, pg.Color("brown"), (100, 250), (200, 250), 10) # prečaga
20
21
# prikazujemo prozor i čekamo da ga korisnik isključi
22
pygamebg.wait_loop()
23

(PyGame_loop__ladder)

Правилно распоређени бројеви

У оба претходна примера било је потребно да набројимо неки низ правилно распоређених бројева. У задатку са круговима то су били бројеви 10, 20, …, 100, а у задатку са мердевинама то су били бројеви 50, 100, 150, 200, 250.

У решењима задатка видели смо да је један начин да се то уради петља облика

3
 
1
for x in range(x0, xMax+1, dx):
2
    ...
3

(petlja1)

при чему је било потребно обратити пажњу на то да десни крај није укључен у набрајање (узимају се вредности из полуотвореног интервала [x0,xMax+1)=[x0,xMax]).

Провери да ли ово разумеш тако што ћеш одговорити на следеће питање.

Q-48: Упари низ бројева са петљом која га генерише.
15, 30, 45, 60, 755, 10, 15, 20, 25, 30100, 200, 300, 400, 500, 600100, 350, 600
for i in range(100, 600+1, 100)for i in range(5, 30+1, 5)for i in range(100, 600+1, 250)for i in range(15, 75+1, 15)

Наведимо још неколико начина да се исти ефекат постигне. Ако почетак обележимо са x0, а корак са dx, тада су вредности које исписујемо x0, x0+dx, x0+2dx, x0+3dx итд. Ако желимо да набројимо n ових вредности, тада можемо употребити петљу облика

4
 
1
for i in range(n):
2
    x = x0 + i * dx
3
    ...
4

(petlja2)

Још један начин је да променљиву x ажурирамо кроз сваки корак петље, тако што је увећавамо за dx.

5
 
1
x = x0
2
for i in range(n):
3
    ...
4
    x += dx
5

(petlja3)

Видећемо да се велики број задатака са цртањем правилно распоређених облика може решити применом оваквих петљи.

Нагласимо још и да функција range са кораком (са три аргумента) прима обавезно целобројне аргументе, па у ситуацијама када корак није целобројан њено коришћење није могуће.

Хоризонтално и вертикално распоређивање облика

Често у применама имамо потребу да распоредимо објекте тако да буду један до другога, тако да су сви објекти равномерно распоређени, тј. тако да су свака два узастопна објекта на истом растојању.

Хоризонтално распоређени кругови

Нацртај 10 кругова пречника 30 пискела тако да буду равномерно распоређени ширином екрана и да се међусобно додирују.

Наредних пар питања ће ти помоћи да решиш овај задатак.

Q-49: Ако се два круга полупречника r додирују, тада је растојање између њихових центара једнако:






Ако круг полупречника r додирује леву ивицу екрана, тада је x координата његовог центра једнака:




На основу овога, допуни наредни програм.

20
 
1
import pygame as pg
2
import pygamebg
3
4
(sirina, visina) = (600, 100) # otvaramo prozor
5
prozor = pygamebg.open_window(sirina, visina, "Хоризонтално распоређени кругови")
6
7
# bojimo pozadinu prozora u belo
8
prozor.fill(pg.Color("white"))
9
10
# crtamo 10 krugova
11
r = 30  # poluprečnik krugova
12
x = ???   # x koordinata centra kruga
13
for i in range(10):
14
    # crtamo krug
15
    pg.draw.circle(prozor, pg.Color("black"), (x, visina // 2), r, 1)
16
    x += ???  # аžuriramo x tako da postane koordinata centra narednog kruga
17
18
# prikazujemo prozor i čekamo da ga korisnik isključi
19
pygamebg.wait_loop()
20

(krugovi_horizontalno)

Још један начин да се овај задатак реши је тај да се примети да су координате центара кругова редом r, r+2r, r+4r, r+6r итд. Дакле, x координата круга са редним бројем i је r+2ir тј. (2i+1)r. Реши задатак коришћењем ове формуле.

18
 
1
import pygame as pg
2
import pygamebg
3
4
(sirina, visina) = (600, 100) # otvaramo prozor
5
prozor = pygamebg.open_window(sirina, visina, "Хоризонтално распоређени кругови")
6
7
# bojimo pozadinu prozora u belo
8
prozor.fill(pg.Color("white"))
9
10
# crtamo 10 krugova
11
r = 30  # poluprečnik krugova
12
for i in range(10):
13
    # crtamo krug
14
    pg.draw.circle(prozor, pg.Color("black"), (???, visina // 2), r, 1)
15
16
# prikazujemo prozor i čekamo da ga korisnik isključi
17
pygamebg.wait_loop()
18

(krugovi_horizontalno_funkcija)

Трећи начин би могао искористити могућност да се функцијом range може вршити набрајање са кораком (нпр. range(r, r + 10*2*r + 1, 2*r)).

Вертикално распоређени кругови

Прикажимо сада како можемо распоредити кругове вертикално.

Напиши програм који црта кругове полупречника 10 пиксела равномерно распоређене вертикално средином екрана, тако да су им центри удаљени 50 пиксела (нацртај све кругове који се виде). Висина екрана се мења приликом сваког покретања програма.

Овај задатак је сличан претходном, уз неколико важних разлика. То што су кругови распоређени вертикално уместо хоризонтално не мења пуно - само је потребно заменити улогу x и y координата. Растојање између полупречника је овај пут фиксно (износи 30 пиксела) и не израчунава се на основу полупречника. Кључна разлика је то што број кругова није унапред задат већ је кругове потребно цртати све док се бар неки њихов делић види на екрану. Зато имамо две могућности. Или ћемо некако на основу висине екрана израчунати број кругова који се виде или ћемо уместо бројачке петље for употребити условну петљу while. Ово друго може бити једноставније.

20
 
1
import random
2
import pygame as pg
3
import pygamebg
4
5
(sirina, visina) = (100, random.randint(150, 500)) # otvaramo prozor
6
prozor = pygamebg.open_window(sirina, visina, "")
7
8
# bojimo pozadinu prozora u belo
9
prozor.fill(pg.Color("white"))
10
11
r = 10  # poluprečnik krugova
12
dy = 30 # vertikalni razmak između centara dva uzastopna kruga
13
y = ???   # y koordinata centra tekućeg kruga
14
while ???:
15
    pg.draw.circle(prozor, pg.Color("red"), (sirina // 2, y), r)  # crtamo krug
16
    y += ???  # centar narednog kruga je udaljen za dy od centra tekućeg kruga
17
18
# prikazujemo prozor i čekamo da ga korisnik isključi
19
pygamebg.wait_loop()
20

(krugovi_vertikalno)

Правоугаона мрежа

Напиши програм који исцртава правоугаону мрежу која се састоји од 100 правоугаоних поља, распоређених у 10 врста и 10 колона (исцртати само линије мреже и то хоризонталне линије плавом бојом, а вертикалне црвеном, дебљине 5 пиксела).

Основни задатак је одредити координате x вертикалних линија и координате y хоризонталних линија. Ширину једног правоугаоника можемо одредити дељењем ширине прозора бројем колона (у нашем случају то је 10), док висину једног правоугаоника можемо одредити дељењем висине прозора бројем врста (то је поново 10). Означимо те димензије са dx и dy. Вертикалне линије се онда налазе на растојању dx, 2dx, 3dx, …, 9dx пиксела од леве ивице прозора (то су им координате x). Пошто се те линије простиру од врха до дна прозора, координате y су им једнаке нули, односно висини прозора. Понављање цртања линија остварујемо, наравно, употребом петље for, при чему је најбоље да се бројач i креће од један до девет, јер се тада у кораку i црта линија од тачке (i*dx, 0) до тачке (i*dx, visina). Цртање хоризонталних линија остварујемо веома слично, у независној петљи for у којој се црта линија од тачке (0, i*dy) до тачке (sirina, i*dy).

23
 
1
import pygame as pg
2
import pygamebg
3
4
(sirina, visina) = (400, 300) # otvaramo prozor
5
prozor = pygamebg.open_window(sirina, visina, "Правоугаона мрежа")
6
7
# bojimo pozadinu prozora u belo
8
prozor.fill(pg.Color("white"))
9
10
brojPodeoka = 10
11
dx = sirina / brojPodeoka
12
dy = ???                   # izračunaj razmak između podeoka po visini
13
14
# crtamo horizontalne linije
15
for i in range(1, brojPodeoka):
16
    pg.draw.line(prozor, pg.Color("blue"), (0, i*dy), (sirina, i*dy), 5)
17
18
# dodaj kod koji crta vertikalne linije crvenom bojom
19
???
20
21
# prikazujemo prozor i čekamo da ga korisnik isključi
22
pygamebg.wait_loop()
23

(pravougaona_mreza)

Још један начин да се одреди координата наредне линије је да се координата претходне линије увећа за ширину тј. дужину правоугаоника.

5
 
1
x = dx
2
for i in range(1, brojPodeoka):
3
    pg.draw.line(prozor, pg.Color("red"), (x, 0), (x, visina), 5)
4
    x += dx
5

(pravougaona_mreza_alt)

Шума

Уместо примитивних геометријских облика (кругова, правоугаоника, дужи и слично) можемо распоређивати сложеније облике и тако добити интересантне цртеже.

Нацртај шуму у којој су јелке распоређене једна до друге тако да се центар прве јелке налази на 100 пиксела од леве ивице екрана и да је размак између сваке две суседне јелке једнак 200 пиксела.

Јелку смо већ цртали у неком од претходних задатака. Претпоставићемо зато да на располагању имамо функцију jelka(x, y) која црта јелку тако да јој је сидро постављено у тачку (x, y), при чему се сидро налази на дну стабла, хоризонтално на његовој средини.

Допуни наредни кôд петљом у којој ће се позивати функција за цртање јелке.

27
 
1
import random
2
import pygame as pg
3
import pygamebg
4
5
(sirina, visina) = (500, 300) # otvaramo prozor
6
prozor = pygamebg.open_window(sirina, visina, "Шума")
7
8
def jelka(x, y):
9
    # boje koje cemo koristiti
10
    CRNA  = (0, 0, 0)
11
    ZELENA = (0, 100, 36)
12
    BRAON = (97, 26, 9)
13
    # stablo
14
    pg.draw.rect(prozor, BRAON, (x-20, y-50, 40, 50))
15
    # krošnja
16
    pg.draw.polygon(prozor, ZELENA, [(x-100, y-50), (x+100, y-50), (x, y-150)])
17
    pg.draw.polygon(prozor, ZELENA, [(x-75, y-100), (x+75, y-100), (x, y-200)])
18
    pg.draw.polygon(prozor, ZELENA, [(x-50, y-150), (x+50, y-150), (x, y-250)])
19
20
# bojimo pozadinu prozora u belo
21
prozor.fill(pg.Color("white"))
22
23
???
24
25
# prikazujemo prozor i čekamo da ga korisnik isključi
26
pygamebg.wait_loop()
27

(suma1)

Штала

Још је лакше ако распоређујемо готове слике учитане из png или jpg датотека.

У штали живи пет кравица. Напиши програм који их распоређује тако да стоје једна поред друге, на дну прозора. Слику кравице учитај из датотеке kravica.png.

Пре него што решиш задатак, подсети се неколико основних функција у вези са сликама.

Q-50: Повежи наредбе са оним чему служе.
slika = pg.image.load("slika.png")slika.get_height()slika.get_width()prozor.blit(slika, (x, y))
приказивање слике на екрануочитавање ширине сликеучитавање слике из датотекеочитавање висине слике

Пре слике са редним бројем i налази се тачно i слика, па се x координата леве ивице те слике може добити множењем ширине слике са i. Пошто слика треба да буде на дну прозора, y координату њеног горњег левог темена можемо израчунати тако што од висине прозора одузмемо висину слике.

Допуни наредни програм на основу претходне дискусије.

../_images/kravica.png
20
 
1
import random
2
import pygame as pg
3
import pygamebg
4
5
(sirina, visina) = (750, 300) # otvaramo prozor
6
prozor = pygamebg.open_window(sirina, visina, "Кравице")
7
8
# bojimo pozadinu u belo
9
prozor.fill(pg.Color("white"))
10
# učitavamo sliku
11
slika = ???
12
# očitavamo dimenzije slike
13
(sirina_slike, visina_slike) = (slika.get_width(), slika.get_height())
14
# pet puta iscrtavamo sliku
15
for i in range(5):
16
    prozor.blit(???)
17
18
# prikazujemo prozor i čekamo da ga korisnik isključi
19
pygamebg.wait_loop()
20

(stala)

Наравно, могуће је било употребити и петљу наредног облика:

3
 
1
for x in range(0, sirina, sirina_slike):
2
    prozor.blit(slika, (x, y))
3

(slika_petlja_sa_korakom)

Домаћи задатак - кућице

Напиши програм који исцртава низ белих кућица дуж једне улице. Kuћица има квадратну основу и кров у облику једнакостраничног троугла. Врата су постављена на средини основе, висина им је пола висине основе, а ширина четвртина ширине основе.

Дефинисаћемо прво функцију која црта једну кућицу. Цртање ћемо вршити релативно у односу на сидро постављено у доње лево теме кућице и димензију (представљену ширином кућице).

../_images/bela_kucica.png

Уз помоћ претходног цртежа израчунај координате свих значајних тачака и допуни програм.

38
 
1
import math, random
2
import pygame as pg
3
import pygamebg
4
5
(sirina, visina) = (600, 300) # otvaramo prozor
6
prozor = pygamebg.open_window(sirina, visina, "Село")
7
8
# crta kućicu kojoj je donje levo teme u (x, y)
9
def kucica(x, y, dim_kucice):
10
    (x0, y0) = (x, y - dim_kucice)  # gornje levo teme osnove
11
    # crtamo osnovu kuće
12
    pg.draw.rect(prozor, pg.Color("white"), (x0, y0, dim_kucice, dim_kucice))
13
    # crtamo krov (jednakostranični trougao)
14
    krov_levo  = (x0, y0)                                                        # donje levo teme krova
15
    krov_desno = (x0 + dim_kucice, y0)                                        # donje desno teme krova
16
    krov_vrh   = (???, ???)                                                      # vrh krova
17
    pg.draw.polygon(prozor, pg.Color("red"), [???, ???, ???])
18
    # uokvirujemo osnovu kuće
19
    ???
20
    # crtamo vrata
21
    sirina_vrata = dim_kucice / 4
22
    visina_vrata = dim_kucice / 2
23
    vrata_levo = ???                         # x koordinata leve ivice vrata
24
    vrata_gore = ???                         # y koordinata gornje ivice vraa
25
    pg.draw.rect(prozor, pg.Color("brown"), ???)
26
27
28
# bojimo pozadinu u nebo-plavo
29
prozor.fill(pg.Color("skyblue"))
30
31
# crtamo jednu po jednu kućicu
32
broj_kucica = 5
33
dim_kucice = sirina / broj_kucica
34
???
35
36
# prikazujemo prozor i čekamo da ga korisnik isključi
37
pygamebg.wait_loop()
38

(kucice)